////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2016-2018 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @file  camxjpegaggrnode.h
/// @brief JPEG aggregator Node class declarations
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/// @todo (CAMX-1988) Code clean up apply NC001 coding standard on entire project
/// @todo (CAMX-1989) Code clean up apply GR030 coding standard on entire project

#ifndef CAMXJPEGAGGRNODE_H
#define CAMXJPEGAGGRNODE_H

#include "camxnode.h"
#include "camxjpegexifparams.h"
#include "camxjpegexifcomposer.h"
#include "camxcsljpegdefs.h"

CAMX_NAMESPACE_BEGIN

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Class that implements the JPEG SW node base class
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class JPEGAggrNode final : public Node
{
public:
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// Create
    ///
    /// @brief  Static method to create JPEGAggrNode Object.
    ///
    /// @param  pCreateInputData  Node create input data
    /// @param  pCreateOutputData Node create output data
    ///
    /// @return Pointer to the concrete JPEGEncNode object
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    static JPEGAggrNode* Create(
        const NodeCreateInputData* pCreateInputData,
        NodeCreateOutputData*      pCreateOutputData);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// Destroy
    ///
    /// @brief  This method destroys the derived instance of the interface
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual VOID Destroy();

protected:
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// ProcessingNodeInitialize
    ///
    /// @brief  Initialize the hwl object
    ///
    /// @param  pCreateInputData  Node create input data
    /// @param  pCreateOutputData Node create output data
    ///
    /// @return CamxResultSuccess if successful
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual CamxResult ProcessingNodeInitialize(
        const NodeCreateInputData* pCreateInputData,
        NodeCreateOutputData*      pCreateOutputData);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetMaxJpegSize
    ///
    /// @brief  Get max jpeg image buffer size from node property
    ///
    /// @param  pCreateInputData  Node create input data
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    VOID GetMaxJpegSize(
        const NodeCreateInputData* pCreateInputData);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// PostPipelineCreate
    ///
    /// @brief  virtual method to be called at NotifyTopologyCreated time; node should take care of updates and initialize
    ///         blocks that has dependency on other nodes in the topology at this time.
    ///
    /// @return CamxResultSuccess if successful
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual CamxResult PostPipelineCreate();

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// ExecuteProcessRequest
    ///
    /// @brief  Pure virtual method to trigger process request for the hwl node object.
    ///
    /// @param  pExecuteProcessRequestData Process request data
    ///
    /// @return CamxResultSuccess if successful and 0 dependencies, dependency information otherwise
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual CamxResult ExecuteProcessRequest(
        ExecuteProcessRequestData* pExecuteProcessRequestData);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// ProcessingNodeFinalizeInputRequirement
    ///
    /// @brief  Virtual method implemented by IPE node to determine its input buffer requirements based on all the output
    ///         buffer requirements
    ///
    /// @param  pBufferNegotiationData  Negotiation data for all output ports of a node
    ///
    /// @return Success if the negotiation was successful, Failure otherwise
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual CamxResult ProcessingNodeFinalizeInputRequirement(
        BufferNegotiationData* pBufferNegotiationData);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// ~JPEGAggrNode
    ///
    /// @brief  Destructor
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual ~JPEGAggrNode();

private:
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// JPEGAggrNode
    ///
    /// @brief  Constructor
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    JPEGAggrNode();
    JPEGAggrNode(const JPEGAggrNode&) = delete;                 ///< Disallow the copy constructor.
    JPEGAggrNode& operator=(const JPEGAggrNode&) = delete;      ///< Disallow assignment operator.

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// SetPropertyDependency
    ///
    /// @brief  Set the dependencey data.
    ///
    /// @param  pNodeRequestData   Pointer to the incoming NodeProcessRequestData
    /// @param  pEnabledPorts      Pointer to active ports
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    VOID SetPropertyDependency(
        NodeProcessRequestData*  pNodeRequestData,
        PerRequestActivePorts*   pEnabledPorts);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// SetBufferDependency
    ///
    /// @brief  Set the buffer dependencies
    ///
    /// @param  pNodeRequestData    Pointer to process request data
    /// @param  pEnabledPorts       Pointer to active ports
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    VOID SetBufferDependency(
        NodeProcessRequestData*   pNodeRequestData,
        PerRequestActivePorts*    pEnabledPorts);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// SetDependencies
    ///
    /// @brief  Check if JPEG aggregator dependencies are met.
    ///
    /// @param  pNodeRequestData    Pointer to process request data
    /// @param  pEnabledPort        Pointer to active ports
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    VOID SetDependencies(
        NodeProcessRequestData*   pNodeRequestData,
        PerRequestActivePorts*    pEnabledPort);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetThumbnailFormat
    ///
    /// @brief  Get image format with thumbnail dimensions.
    ///
    /// @param  pThumbnailFormat Pointer to Thumbanail Image Format
    ///
    /// @return Success if the negotiation was successful, Failure otherwise
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CamxResult GetThumbnailFormat(
        ImageFormat* pThumbnailFormat);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// CheckIfThumbNeeded
    ///
    /// @brief  Check if Thumbnail is needed based on ports and thumb dimensions.
    ///
    /// @param  pExecuteProcessRequestData Process request data
    ///
    /// @return TRUE if thumb needed, False otherwise
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    BOOL CheckIfThumbNeeded(
        ExecuteProcessRequestData* pExecuteProcessRequestData);

    JPEGEXIFParams*    m_pEXIFParams;               ///< JPEG EXIF params
    JPEGEXIFComposer*  m_pEXIFComposer;             ///< JPEG exif composer
    EncoderOutInfo     m_encodeOutParams;           ///< JPEG Encoder outut info
    BOOL               m_rotationHandled;           ///< Is there a previous node that handles the rotation
    UINT32             m_rotatedDimensions[2];      ///< JPEG input width[0] and height[1] after rotation
    EncoderOutInfo     m_encodeOutParamsThumbnail;  ///< JPEG Encoder outut info
};

CAMX_NAMESPACE_END

#endif // CAMXJPEGAGGRNODE_H
